home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / amiga / animutil / playsr / playsr.arc / player.c < prev    next >
C/C++ Source or Header  |  1988-11-10  |  21KB  |  1,176 lines

  1. #include    <intuition/intuition.h>
  2. #include    <intuition/intuitionbase.h>
  3. #include    <devices/timer.h>
  4. #include    <exec/memory.h>
  5. #include    <graphics/gfxbase.h>
  6. #include    <libraries/dosextens.h>
  7. #include    <workbench/startup.h>
  8. #include    <stdio.h>
  9. #include    "defs.h"
  10. #include    "type.h"
  11. #include    "object.h"
  12. #include    "cell.h"
  13. #include    "func.h"
  14. #include    "disp2.h"
  15. #include    "script.h"
  16.  
  17. #define    NUUL_WIDTH    16L
  18. #define    NUUL_HEIGHT    1L
  19.  
  20. #define    IsPal    GfxBase->DisplayFlags & PAL
  21.  
  22. USHORT    nuul_data [] = {
  23.     0x0000, 0x0000,
  24.  
  25.     0x0000, 0x0000,
  26.  
  27.     0x0000, 0x0000
  28. };
  29.  
  30. int    NumPlanes, Mode, Over, Lace;
  31. int    rate = 1;
  32. long    mask = 0;
  33. struct    Screen    *dS[2];
  34. struct    Window    *dW;
  35. struct    IntuitionBase    *IntuitionBase;
  36. struct    GfxBase        *GfxBase;
  37. STLPTR    Movie = NULL, LoopAddr;
  38.  
  39. static struct IntuiText r_bd1 = {0, 1, JAM2,10,10, 0L, (UBYTE *)"Insert next disk", NULL };
  40. static struct IntuiText c_pos = {0, 1, JAM2, 5, 3, 0L, (UBYTE *)"Retry", NULL };
  41. static struct IntuiText c_neg = {0, 1, JAM2, 5, 3, 0L, (UBYTE *)"Cancel", NULL };
  42.  
  43. struct    timerequest    *MyTimer, *CreateTimer ();
  44.  
  45. extern    struct    WBStartup    *WBenchMsg;
  46.  
  47. int    scene_count;
  48. int    loop_count;
  49. int    action_count;
  50. int    delta_count;
  51.  
  52. int    movie_type;
  53.  
  54. USHORT    *action_buffer;
  55. USHORT    **scene_buffer;
  56. ULONG    *delta_buffer;
  57. USHORT    **loop_stack, **ls_limit;
  58. USHORT    **scene_stack, **ss_limit;
  59.  
  60. main (argc, argv)
  61.  
  62. char    **argv;
  63. int    argc;
  64.  
  65. {
  66.     char    fn[256];
  67.     char    arg[256];
  68.     int    Loop, Single;
  69. struct    WBArg    *list;
  70.  
  71.     open_first ();
  72.  
  73.     Loop = 1;
  74.     Single = 0;
  75.  
  76.     if (!argc) {
  77.         argc = WBenchMsg->sm_NumArgs;
  78.         list = WBenchMsg->sm_ArgList;
  79.         list++;
  80.         strcpy (fn, list->wa_Name);
  81.         CurrentDir (list->wa_Lock);
  82.         goto parsed;
  83.     }
  84.  
  85.     if (argc < 2) {
  86.         puts ("Usage: play file [+s] [-l]");
  87.         exit (0);
  88.     }
  89.  
  90.     strcpy (fn, *++argv);
  91.     argc--;
  92.  
  93.     while (--argc) {
  94.         strcpy (arg, *++argv);
  95.  
  96.         if (!strcmp ("-l", arg))
  97.             Loop = 0;
  98.  
  99.         if (!strcmp ("+s", arg))
  100.             Single = 1;
  101.     }
  102.  
  103. parsed:    if (!(MyTimer = CreateTimer (UNIT_MICROHZ))) {
  104.         puts ("Couldn't start timer");
  105.         goto aborts;
  106.     }
  107.  
  108.     if (LoadMovie (fn)) {
  109.         (void) PlayMovie (Loop, Single);
  110.     }
  111.     (void) DumpMovie ();
  112.  
  113. aborts:    close_things ();
  114. }
  115.  
  116. void    SetDS ()
  117.  
  118. {
  119.     if ((movie_type & 0x40) && Mode == 1) {
  120.         DS.Width = 640;
  121.         if (IsPal)
  122.             DS.Height = 256;
  123.         else
  124.             DS.Height = 200;
  125.  
  126.         DW.Width = DS.Width;
  127.         DW.Height = DS.Height;
  128.  
  129.         DS.Depth = 1;
  130.         DS.ViewModes = HIRES;
  131.         return;
  132.     }
  133.  
  134.     DS.Width = 320 + 32 * Over;
  135.  
  136.     if (IsPal)
  137.         DS.Height = 256 + 26 * Over;
  138.     else
  139.         DS.Height = 200 + 20 * Over;
  140.  
  141.     DS.Depth = Mode;
  142.  
  143.     switch (Mode) {
  144.         case 1:
  145.         case 4:
  146.             DS.Width *= 2;
  147.             DS.ViewModes = HIRES;
  148.             break;
  149.         case 5:
  150.             DS.ViewModes = 0;
  151.             break;
  152.         case 6:
  153.             DS.ViewModes = HAM;
  154.             break;
  155.     }
  156.  
  157.     if (Lace) {
  158.         DS.ViewModes |= LACE;
  159.         DS.Height *= 2;
  160.     }
  161.  
  162.     DW.Width = DS.Width;
  163.     DW.Height = DS.Height;
  164. }
  165.  
  166. void    DoOver ()
  167.  
  168. {
  169.     int    i;
  170.     SHORT    vert, horiz;
  171. struct    ViewPort    *v;
  172.  
  173.     if (!Over)
  174.         return;
  175.  
  176.     if (IsPal)
  177.         if (Lace)
  178.             vert = -25;
  179.         else
  180.             vert = -13;
  181.     else
  182.         if (Lace)
  183.             vert = -20;
  184.         else
  185.             vert = -10;
  186.  
  187.     if (Mode == 4)
  188.         horiz = -32;
  189.     else
  190.         horiz = -16;
  191.  
  192.     for (i = 0; i < 2; i++) {
  193.         v = &dS[i]->ViewPort;
  194.         v->DxOffset = horiz;
  195.         v->DyOffset = vert;
  196.     }
  197.  
  198.     RemakeDisplay ();            /* Ugh!            */
  199. }
  200.  
  201. open_first ()
  202.  
  203. {
  204.     if(!(IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library",0L))) {
  205.         puts("no intuition here!");
  206.         close_things();
  207.         exit(1);
  208.     }
  209.     mask |= INTUITION;
  210.  
  211.     if(!(GfxBase = (struct GfxBase *) OpenLibrary("graphics.library",0L))) {
  212.         puts("no graphics library!");
  213.         close_things();
  214.         exit(2);
  215.     }
  216.     mask |= GRAPHICS;
  217. }
  218.  
  219.  
  220. open_last ()
  221.  
  222. {
  223.     if (!(dS[0]=(struct Screen *)OpenScreen(&DS))) {
  224.         puts("no display screen");
  225.         close_things();
  226.         exit(3);
  227.     }
  228.  
  229.     if (!(dS[1]=(struct Screen *)OpenScreen(&DS))) {
  230.         puts("no display screen");
  231.         close_things();
  232.         exit(4);
  233.     }
  234.  
  235.     DW.Screen = dS[1];
  236.     if (!(dW=(struct Window *) OpenWindow(&DW))) {
  237.         puts ("no display window");
  238.         close_things();
  239.         exit(5);
  240.     }
  241. }
  242.  
  243. void    close_things()
  244.  
  245. {
  246.     if (dW)    
  247.         CloseWindow(dW);
  248.     if (dS[0])
  249.         CloseScreen(dS[0]);
  250.     if (dS[1])
  251.         CloseScreen(dS[1]);
  252.     if (mask & GRAPHICS)    CloseLibrary(GfxBase);
  253.     if (mask & INTUITION) {
  254.         OpenWorkBench ();
  255.         CloseLibrary(IntuitionBase);
  256.     }
  257. }
  258.  
  259. STLPTR    AddStill (st, pl)
  260.  
  261. STLPTR    st;
  262. int    pl;
  263.  
  264. {
  265.     int    i;
  266.     STLPTR    node, temp = st;
  267.  
  268.     node = AllocMem ((long) sizeof (STILL), 0L);
  269.     if (node) {
  270.         node->Next = NULL;
  271.         for (i = 0; i < NumPlanes; i++) {
  272.             node->Planes[i] = NULL;
  273.             node->Size[i] = 0;
  274.         }
  275.         if (temp) {
  276.             while (temp->Next)
  277.                 temp = temp->Next;
  278.             temp->Next = node;
  279.         }
  280.     }
  281.     return node;
  282. }
  283.  
  284. LoadMovie (fn)
  285.  
  286. char    *fn;
  287.  
  288. {
  289.     char    sn[256], title[256];
  290.     long    fp, Open (), Read ();
  291.     UBYTE    data;
  292.     int    i, pl, lace, fr, loop, blop;
  293.     long    res, qq;
  294.     STLPTR    curr;
  295.     FILE    *sp, *fopen ();
  296.  
  297.     (void) DumpMovie ();
  298.     Movie = NULL;
  299.     LoopAddr = NULL;
  300.     loop = -1;
  301.  
  302.     sp = NULL;
  303.     fp = NULL;
  304.  
  305.     sprintf (sn, "%s/script", fn);
  306.  
  307.     if (!(sp = fopen (sn, "r"))) {
  308.         puts("Can't open script");
  309.         return FALSE;
  310.     }
  311.  
  312.     i = 0;
  313.     do {
  314.         if (!(fread (&title[i], 1, 1, sp)))
  315.             goto load_err;
  316.     } while (title[i++] != '\n');
  317.     i--;
  318.  
  319.     if (!(fread (&data, 1, 1, sp)))
  320.         goto load_err;
  321.  
  322.     movie_type = pl = data;
  323.     NumPlanes = pl & 7;
  324.  
  325.     Mode = pl & 7;
  326.     Over = (pl & 16) >> 4;
  327.     Lace = (pl & 8) >> 3;
  328.  
  329.     SetDS ();
  330.     open_last ();
  331.  
  332.     SetAPen (dW->RPort, 1L);
  333.     Move (dW->RPort, 0L, 10L);
  334.     Text (dW->RPort, title, (long) i);
  335.  
  336.     SetPointer (dW, nuul_data, NUUL_HEIGHT, NUUL_WIDTH, 0L, 0L);
  337.  
  338.     if(pl & 0x40)
  339.         return FinishLoad(sp, fn);    /* new format */
  340.  
  341.     if (!(fread (&data, 1, 1, sp)))
  342.         goto load_err;
  343.     rate = data;
  344.  
  345.     if (!(fread (&blop, 2, 1, sp)))
  346.         goto load_err;
  347.     fr = blop;
  348.  
  349.     while (fr >= 0) {
  350.         curr = AddStill (Movie);
  351.         if (!curr)
  352.             return FALSE;
  353.         curr->frame = fr;
  354.         if (!Movie) {
  355.             Movie = curr;
  356.             LoopAddr = curr;
  357.         }
  358.  
  359.         sprintf (sn, "%s/ANIM.%d", fn, fr);
  360.  
  361.         for (;;) {
  362.             if (fp = Open (sn, 1005L))
  363.                 break;
  364.  
  365.             if (!AutoRequest (dW, &r_bd1, &c_pos, &c_neg, 0L, 0L, 280L, 80L))
  366.                 goto load_err;
  367.         }
  368.  
  369.         res = Read (fp, &curr->CMap[0], 64L);
  370.         if (res < 64)
  371.             goto load_err;
  372.  
  373.         for (i = 0; i < NumPlanes; i++) {
  374.             res = Read (fp, &curr->Size[i], 2L);
  375.             if (res < 2)
  376.                 goto load_err;
  377.  
  378.             qq = ((long) curr->Size[i] << 1);
  379.  
  380.             if (!(curr->Planes[i] = AllocMem (qq, 0L)))
  381.                 goto load_err;
  382.  
  383.             res = Read (fp, curr->Planes[i], qq);
  384.             if (res < qq)
  385.                 goto load_err;
  386.         }
  387.         Close (fp);
  388.         fp = NULL;
  389.  
  390.         if (!(fread (&blop, 2, 1, sp)))
  391.             goto load_err;
  392.         fr = blop;
  393.     }
  394.     if (!(fread (&blop, 2, 1, sp)))
  395.         goto load_err;
  396.     loop = blop;
  397.  
  398.     if (loop > -1)
  399.         while (loop--)
  400.             if (LoopAddr)
  401.                 LoopAddr = LoopAddr->Next;
  402.  
  403.     fclose (sp);
  404.     return TRUE;
  405.  
  406. load_err:
  407.     if (sp)
  408.         fclose (sp);
  409.     if (fp)
  410.         Close (fp);
  411.     return FALSE;
  412. }
  413.  
  414. void    DumpMovie ()
  415.  
  416. {
  417.     STLPTR    temp;
  418.     int    i;
  419.  
  420.     while (Movie) {
  421.         temp = Movie;
  422.         Movie = Movie->Next;
  423.         for (i = 0; i < NumPlanes; i++)
  424.             MyFreeMem (temp->Planes[i], 2L * temp->Size[i]);
  425.         MyFreeMem (temp, (long) sizeof (STILL));
  426.     }
  427.  
  428.     MyFreeMem(scene_buffer, 4L * scene_count);
  429.     MyFreeMem(action_buffer, 4L * action_count);
  430.     MyFreeMem(delta_buffer, 8L * delta_count);
  431.     MyFreeMem(scene_stack, 8L * (scene_count + 2));
  432.     MyFreeMem(loop_stack, 8L * (loop_count + 2));
  433.     scene_buffer = NULL;
  434.     action_buffer = NULL;
  435.     delta_buffer = NULL;
  436.     scene_stack = NULL;
  437.     loop_stack = NULL;
  438.     scene_count = 0;
  439.     loop_count = 0;
  440.     action_count = 0;
  441.     delta_count = 0;
  442. }
  443.  
  444. void    PlayMovie (flag, step)
  445.  
  446. int    flag, step;
  447.  
  448. {
  449.     int    FrmPos, pause, restart;
  450.     long    wait;
  451.     char    s[6];
  452.     ULONG    CLA;
  453.     USHORT    COD;
  454.     UBYTE    flip;
  455.     STLPTR    play;
  456. struct    IntuiMessage    *MSG;
  457.  
  458.     DoOver ();
  459.  
  460.     SetRGB4 (&dS[0]->ViewPort, 0L, 0L, 0L, 0L);
  461.     SetDrMd (&dS[0]->RastPort, JAM1);
  462.     SetAPen (&dS[0]->RastPort, 0L);
  463.  
  464.     SetRGB4 (&dS[1]->ViewPort, 0L, 0L, 0L, 0L);
  465.     SetDrMd (&dS[1]->RastPort, JAM1);
  466.     SetAPen (&dS[1]->RastPort, 0L);
  467.  
  468.     if(movie_type & 0x40) {
  469.         NewPlay(flag, step);
  470.         return;
  471.     }
  472.  
  473.     restart = 0;
  474.     flip = 0;                /* Even frame        */
  475.     play = Movie;                /* Beginning of movie    */
  476.     if (!flag)
  477.         LoopAddr = NULL;
  478.  
  479.     wait = ((long) rate - 1L) * 16667L;
  480.     if (wait < 0)
  481.         wait = 0;
  482.  
  483.     FrmPos = 0;
  484.  
  485.     while (play) {
  486.         if (restart) {
  487.             restart = 0;
  488.             FrmPos = 0;
  489.             flip = 0;
  490.             play = Movie;
  491.             RectFill (&dS[1]->RastPort, 0L, 0L, DS.Width - 1L, DS.Height - 1L);
  492.             WaitBlit ();
  493.             ScreenToFront (dS[1]);
  494.         }
  495.  
  496.         if (FrmPos < 2) {
  497.             RectFill (&dS[flip]->RastPort, 0L, 0L, DS.Width - 1L, DS.Height - 1L);
  498.             WaitBlit ();
  499.         }
  500.  
  501.         FrmPos++;
  502.  
  503.         if (IntuitionBase->ActiveWindow != dW)
  504.             ActivateWindow (dW);
  505.  
  506.         MyTimer->tr_node.io_Command = TR_ADDREQUEST;
  507.         MyTimer->tr_time.tv_secs = 0;
  508.         MyTimer->tr_time.tv_micro = wait;
  509.  
  510.         if (!step)
  511.             SendIO (MyTimer);
  512.  
  513.         ExpFrame (play, flip);
  514.         LoadRGB4 (&dS[flip]->ViewPort, &play->CMap[0], 32L);
  515.  
  516.         if (!step)
  517.             if (!CheckIO (MyTimer))
  518.                 WaitIO (MyTimer);
  519.  
  520.         WaitTOF ();
  521.         ScreenToFront (dS[flip]);
  522.  
  523.         pause = step;
  524.  
  525.         do {
  526.             while (MSG = GetMsg(dW->UserPort)){
  527.                 CLA = MSG->Class;
  528.                 COD = MSG->Code;
  529.                 ReplyMsg(MSG);
  530.                 if (CLA == RAWKEY) {
  531.                     switch (COD) {
  532.                         case 68:
  533.                             restart = 1;
  534.                             break;
  535.                         case 64:
  536.                             if (!step)
  537.                                 step = 1;
  538.                             else
  539.                                 pause = 0;
  540.                             break;
  541.                         case 11:
  542.                             pause = 0;
  543.                             step = 0;
  544.                             if (rate < 60)
  545.                                 rate++;
  546.                             break;
  547.                         case 12:
  548.                             pause = 0;
  549.                             step = 0;
  550.                             if (rate)
  551.                                 rate--;
  552.                             break;
  553.                         case 80:
  554.                         case 81:
  555.                         case 82:
  556.                         case 83:
  557.                         case 84:
  558.                         case 85:
  559.                         case 86:
  560.                         case 87:
  561.                         case 88:
  562.                         case 89:
  563.                             pause = 0;
  564.                             step = 0;
  565.                             rate = (COD - 80) * 6;
  566.                             break;
  567.                         case 69:
  568.                             goto stop;
  569.                     }
  570.                 }
  571.             }
  572.         } while (pause);
  573.  
  574.         wait = ((long) rate - 1L) * 16667L;
  575.         if (wait < 0)
  576.             wait = 0;
  577.  
  578.         flip = 1 - flip;
  579.         play = play->Next;
  580.         if (!play && LoopAddr) {    /* If end & loop    */
  581.             play = LoopAddr;    /* Send it back        */
  582.             if (play == Movie)
  583.                 FrmPos = 0;
  584.             else
  585.                 FrmPos = 2;
  586.         }
  587.     }
  588.  
  589. stop:    DeleteTimer (MyTimer);
  590.  
  591. }
  592.  
  593. void    ExpFrame (ptr, f)
  594.  
  595. STLPTR    ptr;
  596. UBYTE    f;
  597.  
  598. {
  599. struct    BitMap    *bm;
  600.     UWORD    *src, *trg;
  601. UWORD    packet;
  602. int    pl;
  603.  
  604.     bm = &dS[f]->BitMap;
  605.     for (pl = 0; pl < NumPlanes; pl++) {
  606.         src = (UWORD *)ptr->Planes[pl];
  607.         trg = (UWORD *)bm->Planes[pl];
  608.         packet = *src++;
  609. #asm
  610.     movea.l    -8(a5),a0        ;source
  611.     movea.l    -12(a5),a1        ;target
  612.     move.w    -14(a5),d2        ;packet count
  613.     bmi    .1003            ;wow! no changes!
  614.     clr.l    d1            ;make this pretty
  615.  
  616. .1000    move.l    (a0)+,d0        ;get source word
  617.     beq    .1002            ;possible skip count
  618.  
  619. .1001    move.l    d0,(a1)+        ;put word in target
  620.     dbf    d2,.1000        ;more packets
  621.     bra    .1003            ;we be jammin'
  622.  
  623. .1002    move.w    (a0)+,d1        ;number of words to skip
  624.     beq    .1001            ;oops! really want a zero
  625.     asl.l    #2,d1
  626.     adda.l    d1,a1            ;adjust target address
  627.     dbf    d2,.1000        ;more packets
  628.  
  629. .1003
  630. #endasm
  631.     }
  632. }
  633.  
  634. void    NewExpFrame (ptr, bm)
  635.  
  636. STLPTR    ptr;
  637. struct    BitMap    *bm;
  638.  
  639. {
  640.     UWORD    *src, *trg;
  641.     UWORD    packet;
  642.     int    pl;
  643.  
  644.     for (pl = 0; pl < NumPlanes; pl++) {
  645.         src = (UWORD *) ptr->Planes[pl];
  646.         trg = (UWORD *) bm->Planes[pl];
  647.         packet = *src++;
  648. #asm
  649.     movea.l    -4(a5),a0        ;source
  650.     movea.l    -8(a5),a1        ;target
  651.     move.w    -10(a5),d2        ;block count
  652.     bmi    .1013
  653.  
  654. .1010    move.w    (a0)+,d1        ;get longword count
  655.     adda.l    (a0)+,a1        ;add in destination offset
  656.  
  657. .1011    move.l    (a0)+,(a1)+        ;put longwords in target
  658.     dbra    d1,.1011        ;loop through block
  659.  
  660. .1012    dbra    d2,.1010        ;loop blocks
  661.  
  662. .1013
  663. #endasm
  664.     }
  665. }
  666.  
  667. FinishLoad (sp, fn)
  668.  
  669. FILE    *sp;
  670. char    *fn;
  671.  
  672. {
  673.     char    dn[256], sn[256];
  674.     LONG    fp = 0;
  675.     int    i, j, fr, loop, deln;
  676.     LONG    qq, res;
  677.     STLPTR    curr;
  678.     USHORT    *a, **s;
  679.     ULONG    *d;
  680.  
  681.     int    scene_cnt;
  682.     int    loop_cnt;
  683.     int    action_cnt;
  684.     int    delta_cnt;
  685.  
  686.     scene_count = 0;
  687.     loop_count = 0;
  688.     action_count = 0;
  689.     delta_count = 0;
  690.  
  691.     if(!fread(&scene_cnt, 2, 1, sp))
  692.         goto load_err;
  693.     if(!fread(&loop_cnt, 2, 1, sp))
  694.         goto load_err;
  695.     if(!fread(&action_cnt, 2, 1, sp))
  696.         goto load_err;
  697.     if(!fread(&delta_cnt, 2, 1, sp))
  698.         goto load_err;
  699.  
  700.     if(!action_cnt || !scene_cnt || !delta_cnt) {
  701.         fclose(sp);
  702.         return FALSE;
  703.     }
  704.  
  705.     action_buffer = (USHORT *)AllocMem(action_cnt * 4L, 0L);
  706.     scene_buffer = (USHORT **)AllocMem(scene_cnt * 4L, 0L);
  707.     delta_buffer = (ULONG *)AllocMem(delta_cnt * 8L, 0L);
  708.     scene_stack = (USHORT **)AllocMem((scene_cnt + 2) * 8L, 0L);
  709.     loop_stack = (USHORT **)AllocMem((loop_cnt + 2) * 8L, 0L);
  710.  
  711.     if(!scene_buffer || !action_buffer || !delta_buffer || !scene_stack || !loop_stack) {
  712.         fclose(sp);
  713.         return FALSE;
  714.     }
  715.     ss_limit = scene_stack + 2 * (scene_cnt + 2);
  716.     ls_limit = loop_stack + 2 * (loop_cnt + 2);
  717.  
  718.     if(fread(action_buffer, 4, action_cnt, sp) != action_cnt)
  719.         goto load_err;
  720.     if(fread(delta_buffer, 8, delta_cnt, sp) != delta_cnt)
  721.         goto load_err;
  722.     fclose (sp);
  723.  
  724.     s = scene_buffer;
  725.     a = action_buffer;
  726.     for(i = 0; i < scene_cnt; i++) {
  727.         *s++ = a;
  728.         while(*a)
  729.             a += 2;
  730.         a += 2;
  731.     }
  732.  
  733.     i = delta_cnt;
  734.     d = delta_buffer;
  735.     deln = 1;
  736.  
  737.     while (deln <= delta_cnt) {
  738.         curr = AddStill (Movie);
  739.         if (!curr) {
  740.             fclose (sp);
  741.             return FALSE;
  742.         }
  743.  
  744.         if (!Movie)
  745.             Movie = curr;
  746.  
  747.         curr->frame = d[1];
  748.  
  749.         sprintf (sn, "%s/ANIM.%d", fn, deln);
  750.  
  751.         for (;;) {
  752.             if (fp = Open (sn, 1005L))
  753.                 break;
  754.  
  755.             if (!AutoRequest (dW, &r_bd1, &c_pos, &c_neg, 0L, 0L, 280L, 80L))
  756.                 goto load_err;
  757.         }
  758.  
  759.         res = Read (fp, &curr->CMap[0], 64L);
  760.         if (res < 64)
  761.             goto load_err;
  762.  
  763.         for (i = 0; i < NumPlanes; i++) {
  764.             res = Read (fp, &curr->Size[i], 2L);
  765.             if (res < 2)
  766.                 goto load_err;
  767.  
  768.             qq = ((long) curr->Size[i] << 1);
  769.  
  770.             if (!(curr->Planes[i] = AllocMem (qq, 0L)))
  771.                 goto load_err;
  772.  
  773.             res = Read (fp, curr->Planes[i], qq);
  774.             if (res < qq)
  775.                 goto load_err;
  776.         }
  777.         Close (fp);
  778.         fp = NULL;
  779.  
  780.         deln++;
  781.         d += 2;
  782.     }
  783.  
  784.     fclose(sp);
  785.  
  786.     scene_count = scene_cnt;
  787.     loop_count = loop_cnt;
  788.     action_count = action_cnt;
  789.     delta_count = delta_cnt;
  790.  
  791.     return TRUE;
  792.  
  793. load_err:
  794.     if (sp)
  795.         fclose (sp);
  796.     if (fp)
  797.         Close (fp);
  798.     return FALSE;
  799. }
  800.  
  801. recursion_error()
  802. {
  803.     puts("Error: Infinite recursion");
  804. }
  805.  
  806. NewPlay (flag, step)
  807. int    flag, step;
  808. {
  809.     int    pause;
  810.     char    s[6];
  811.     long    wait;
  812.     ULONG    CLA;
  813.     USHORT    COD;
  814.     UBYTE    flip;
  815.     STLPTR    play;
  816.     USHORT    *action;
  817.     ULONG    *dl;
  818.     USHORT    *ap;
  819.     ULONG    frame[2];
  820.     int    palette_number;
  821.     int    palette_num;
  822.     int    plocked;
  823.     int    plock;
  824.     int    front, swap;
  825.     LONG    from, toom;
  826.     int    i, restart;
  827.     int    in_loop, break_loop, break_loop2;
  828.     USHORT    **loop_sp;
  829.     USHORT    **scene_sp;
  830.     USHORT    **lsp, **lsp2;
  831.     USHORT    **ssp, **ssp2;
  832.     LONG    secs, micros;
  833. struct    IntuiMessage    *MSG;
  834.  
  835. top:
  836.  
  837.     RectFill (&dS[0]->RastPort, 0L, 0L, DS.Width - 1L, DS.Height - 1L);
  838.     RectFill (&dS[1]->RastPort, 0L, 0L, DS.Width - 1L, DS.Height - 1L);
  839.     WaitBlit ();
  840.  
  841.     front = 0;                /* Even frame        */
  842.     action = (USHORT *)action_buffer;    /* Beginning of movie    */
  843.     frame[0] = frame[1] = 0;        /* current cell #'s     */
  844.     plocked = 0;                /* palette not locked */
  845.     palette_number = -1;            /* no palette yet */
  846.  
  847.     ScreenToFront (dS[0]);            /* proper screen in front */
  848.  
  849.     restart = 0;
  850.     pause = 0;
  851.  
  852.     loop_sp = loop_stack;
  853.     scene_sp = scene_stack;
  854.     in_loop = break_loop = break_loop2 = FALSE;
  855.  
  856.     wait = ((long) rate - 1L) * 16667L;
  857.     if (wait < 0)
  858.         wait = 0L;
  859.  
  860.     for(;;) {
  861.         if (IntuitionBase->ActiveWindow != dW)
  862.             ActivateWindow (dW);
  863.  
  864.         MyTimer->tr_node.io_Command = TR_ADDREQUEST;
  865.         MyTimer->tr_time.tv_secs = 0;
  866.         MyTimer->tr_time.tv_micro = wait;
  867.  
  868.         if (!step)
  869.             SendIO (MyTimer);
  870.  
  871.         ap = action;
  872.  
  873.         ssp = scene_sp;
  874.         ssp2 = scene_stack;
  875.         while(ssp2 != scene_sp) {
  876.             if(ssp == ss_limit) {
  877.                 recursion_error();
  878.                 break;
  879.             }
  880.             *ssp++ = *ssp2++;
  881.         }
  882.  
  883.         lsp = loop_sp;
  884.         lsp2 = loop_stack;
  885.         while(lsp2 != loop_sp) {
  886.             if(lsp == ls_limit) {
  887.                 recursion_error();
  888.                 break;
  889.             }
  890.             *lsp++ = *lsp2++;
  891.         }
  892.  
  893.         palette_num = palette_number;
  894.         plock = plocked;
  895.  
  896.         for(;;) {
  897.             if(*ap == ACT_EXPAND || *ap == ACT_BLACK)
  898.                 break;
  899.             else if(*ap == ACT_SCENE) {
  900.                 if(ssp == ss_limit) {
  901.                     ap = action;
  902.                     break;
  903.                 }
  904.                 *ssp++ = ap + 2;
  905.                 ap = scene_buffer[*(ap + 1)];
  906.             } else if(*ap == ACT_END) {
  907.                 if(ssp == scene_sp)
  908.                     break;
  909.                 ap = *--ssp;
  910.             } else if(*ap == ACT_STARTLOOP) {
  911.                 if(lsp == ls_limit) {
  912.                     ap = action;
  913.                     break;
  914.                 }
  915.                 *lsp++ = ap;
  916.                 *(LONG *)lsp++ = -1L;
  917.                 ap += 2;
  918.             } else if(*ap == ACT_ENDLOOP) {
  919.                 if(*(LONG *)(lsp - 1) == -1) {
  920.                     lsp -= 2;
  921.                     ap += 2;
  922.                 } else if(*(LONG *)(lsp - 1) == 0xffffL) {
  923.                     ap = *(lsp - 2) + 2;
  924.                     *(LONG *)(lsp - 1) = -1L;
  925.                     in_loop = TRUE;
  926.                 } else if(++*(LONG *)(lsp - 1) == *(ap + 1)) {
  927.                     lsp -= 2;
  928.                     ap += 2;
  929.                 } else {
  930.                     ap = *(lsp - 2) + 2;
  931.                     *(LONG *)(lsp - 1) = -1L;
  932.                 }
  933.             } else if(*ap == ACT_LOCK) {
  934.                 plock = TRUE;
  935.                 palette_num = -1;
  936.                 ap += 2;
  937.             } else if(*ap == ACT_FREE) {
  938.                 plock = FALSE;
  939.                 ap += 2;
  940.             } else
  941.                 ap += 2;
  942.         }
  943.  
  944.         if(*ap == ACT_EXPAND) {
  945.             if(!plock || palette_num < 0)
  946.                 palette_num = ((movie_type != 0x61) ? *(ap + 1) : 0);
  947.             toom = *(ap + 1) | ((long)palette_num  << 16);
  948.         } else if(*ap == ACT_BLACK)
  949.             toom = 0;
  950.         else
  951.             toom = -1;
  952.  
  953.         if(toom < 0 || toom == frame[front])
  954.             swap = FALSE;
  955.         else {
  956.             swap = TRUE;
  957.             front ^= 1;
  958.         }
  959.         if(swap && toom != frame[front]) {
  960.             if(!toom) {
  961.                 RectFill (&dS[front]->RastPort, 0L, 0L, DS.Width - 1L, DS.Height - 1L);
  962.                 frame[front] = 0;
  963.             } else {
  964.  
  965.                 from = frame[front];
  966.  
  967.                 play = Movie;
  968.                 dl = delta_buffer;
  969.                 i = delta_count;
  970.                 while(i--) {
  971.                     if(*dl == from && *(dl + 1) == toom)
  972.                         break;
  973.                     dl += 2;
  974.                     play = play->Next;
  975.                 }
  976.  
  977.                 if(play) {
  978.                     LoadRGB4 (&dS[front]->ViewPort, &play->CMap[0], 32L);
  979.                     NewExpFrame (play, &dS[front]->BitMap);
  980.                     frame[front] = toom;
  981.                 } else {
  982.                     puts("Internal error");
  983.                     break;
  984.                 }
  985.             }
  986.         }
  987.  
  988.         if (!step)
  989.             if (!CheckIO (MyTimer))
  990.                 WaitIO (MyTimer);
  991.  
  992. nextac:        while(*action != ACT_EXPAND && *action != ACT_BLACK) {
  993.             if(*action == ACT_SCENE) {
  994.                 if(scene_sp == ss_limit) {
  995.                     recursion_error();
  996.                     action = NULL;
  997.                     break;
  998.                 }
  999.                 *scene_sp++ = action + 2;
  1000.                 action = scene_buffer[*(action + 1)];
  1001.             } else if(*action == ACT_END) {
  1002.                 if(scene_sp == scene_stack)
  1003.                     break;
  1004.                 action = *--scene_sp;
  1005.             } else if(*action == ACT_STARTLOOP) {
  1006.                 if(loop_sp == ls_limit) {
  1007.                     recursion_error();
  1008.                     action = NULL;
  1009.                     break;
  1010.                 }
  1011.                 *loop_sp++ = action;
  1012.                 *loop_sp++ = 0;
  1013.                 action += 2;
  1014.             } else if(*action == ACT_ENDLOOP) {
  1015.                 ap = *(loop_sp - 2);
  1016.                 if(*(action + 1) == 0xffff) {
  1017.                     if(in_loop && break_loop) {
  1018.                         in_loop = break_loop = FALSE;
  1019.                         *(loop_sp - 1) = -1L;
  1020.                         break_loop2 = TRUE;
  1021.                         action = ap + 2;
  1022.                     } else if(break_loop2) {
  1023.                         break_loop2 = FALSE;
  1024.                         loop_sp -= 2;
  1025.                         action += 2;
  1026.                     } else {
  1027.                         action = ap + 2;
  1028.                         *(loop_sp - 1) = 0xffffL;
  1029.                     }
  1030.                 } else if(++*(LONG *)(loop_sp - 1) == *(action + 1)) {
  1031.                     loop_sp -= 2;
  1032.                     action += 2;
  1033.                 } else
  1034.                     action = ap + 2;
  1035.             } else if(*action == ACT_RATE) {
  1036.                 rate = *(action + 1);
  1037.                 action += 2;
  1038.             } else if(*action == ACT_LOCK) {
  1039.                 plocked = TRUE;
  1040.                 palette_number = -1;
  1041.                 action += 2;
  1042.             } else if(*action == ACT_FREE) {
  1043.                 plocked = FALSE;
  1044.                 action += 2;
  1045.             } else
  1046.                 break;
  1047.         }
  1048.  
  1049.         if(!action || *action == ACT_END)
  1050.             break;
  1051.  
  1052.         if(*action == ACT_EXPAND || *action == ACT_BLACK) {
  1053.             if(swap) {
  1054.                 WaitTOF ();
  1055.                 ScreenToFront (dS[front]);
  1056.             }
  1057.             palette_number = palette_num;
  1058.         } else if(*action == ACT_PAUSE) {
  1059.  
  1060.             micros = *(action + 1) * 16667L;
  1061.             secs = micros / 1000000L;
  1062.             micros = micros % 1000000L;
  1063.  
  1064.             MyTimer->tr_node.io_Command = TR_ADDREQUEST;
  1065.             MyTimer->tr_time.tv_secs = secs;
  1066.             MyTimer->tr_time.tv_micro = micros;
  1067.  
  1068.             if (!step) {
  1069.                 SendIO (MyTimer);
  1070.  
  1071.                 if (!CheckIO (MyTimer))
  1072.                     WaitIO (MyTimer);
  1073.             }
  1074.         } else if(*action == ACT_HOLD) {
  1075.             i = 1;
  1076.             while(i) {
  1077.                 Wait(1L << dW->UserPort->mp_SigBit);
  1078.                 while (MSG = (struct IntuiMessage *) GetMsg(dW->UserPort)){
  1079.                     CLA = MSG->Class;
  1080.                     COD = MSG->Code;
  1081.                     ReplyMsg (MSG);
  1082.                     if (CLA == RAWKEY && COD == 64)
  1083.                         i = 0;
  1084.                 }
  1085.             }
  1086.         }
  1087.  
  1088.         pause = step;
  1089.  
  1090.         do {
  1091.             while (MSG = (struct IntuiMessage *)GetMsg(dW->UserPort)){
  1092.                 CLA = MSG->Class;
  1093.                 COD = MSG->Code;
  1094.                 ReplyMsg(MSG);
  1095.                 if (CLA == RAWKEY) {
  1096.                     switch (COD) {
  1097.                         case 68:
  1098.                             restart = 1;
  1099.                             break;
  1100.                         case 51:
  1101.                             if(in_loop)
  1102.                                 break_loop = TRUE;
  1103.                             break;
  1104.                         case 64:
  1105.                             if (!step)
  1106.                                 step = 1;
  1107.                             else
  1108.                                 pause = 0;
  1109.                             break;
  1110.                         case 11:
  1111.                             pause = 0;
  1112.                             step = 0;
  1113.                             if (rate < 60)
  1114.                                 rate++;
  1115.                             break;
  1116.                         case 12:
  1117.                             pause = 0;
  1118.                             step = 0;
  1119.                             if (rate)
  1120.                                 rate--;
  1121.                             break;
  1122.                         case 80:
  1123.                         case 81:
  1124.                         case 82:
  1125.                         case 83:
  1126.                         case 84:
  1127.                         case 85:
  1128.                         case 86:
  1129.                         case 87:
  1130.                         case 88:
  1131.                         case 89:
  1132.                             pause = 0;
  1133.                             step = 0;
  1134.                             rate = (COD - 80) * 6;
  1135.                             break;
  1136.                         case 69:
  1137.                             goto stop;
  1138.                     }
  1139.                 }
  1140.             }
  1141.         } while (pause && !restart);
  1142.  
  1143.         if(restart)
  1144.             goto top;
  1145.  
  1146.         wait = ((long) rate - 1L) * 16667L;
  1147.         if (wait < 0)
  1148.             wait = 0L;
  1149.  
  1150.         if(*action != ACT_EXPAND && *action != ACT_BLACK) {
  1151.             action += 2;
  1152.             goto nextac;
  1153.         }
  1154.  
  1155.         if(*action == ACT_BLACK) {
  1156.                 RectFill (&dS[front ^ 1]->RastPort, 0L, 0L, DS.Width - 1L, DS.Height - 1L);
  1157.                 frame[front ^ 1] = 0;
  1158.         }
  1159.         action += 2;
  1160.     }
  1161.  
  1162.     if (flag)
  1163.         goto top;
  1164.  
  1165. stop:
  1166.     DeleteTimer (MyTimer);
  1167. }
  1168.  
  1169. void    MyFreeMem(addr, size)
  1170. LONG    *addr;
  1171. LONG    size;
  1172. {
  1173.     if(addr && size)
  1174.         FreeMem(addr, size);
  1175. }
  1176.